﻿using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Web;
using System.Data;
using System.Net;
namespace RegexJson.Common
{

	/// <summary>
	/// 工具类
	/// </summary>
    public class Utils
    {

        
        #region string类型转换
        /// <summary>
        /// string型转换为bool型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的bool类型结果</returns>
        public static bool StringToBool(object Expression, bool defValue)
        {
            return TypeParse.StrToBool(Expression, defValue);
        }

        /// <summary>
        /// string型转换为Time型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的Time类型结果</returns>
        public static DateTime StringToDataTime(object Expression)
        {
            DateTime dt = new DateTime();
            DateTime.TryParse(Expression.ToString(), out dt);
            return dt;
        }

        /// <summary>
        /// 将对象转换为Int32类型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static int StringToInt(object Expression, int defValue)
        {
            return TypeParse.StrToInt(Expression, defValue);
        }

        /// <summary>
        /// string型转换为float型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static float StringToFloat(object strValue, float defValue)
        {
            return TypeParse.StrToFloat(strValue, defValue);
        }

        /// <summary>
        /// string型转换为decimal型
        /// </summary>
        /// <param name="strValue"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public static decimal StringToDecimal(string strValue, decimal defValue)
        {
            decimal de = new decimal();
            decimal.TryParse(strValue, out de);
            return de;
        }
        #endregion
        #region URL 字符串的编码结果
        /// <summary>
        /// 返回 URL 字符串的编码结果
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>编码结果</returns>
        public static string UrlEncode(string str)
        {
            return HttpUtility.UrlEncode(str);
        }

        /// <summary>
        /// 返回 URL 字符串的编码结果
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>解码结果</returns>
        public static string UrlDecode(string str)
        {
            return HttpUtility.UrlDecode(str);
        }
        #endregion
        #region 采集
        /// <summary>
        /// 获取指定远程网页内容
        /// </summary>
        /// <param name="strUrl">所要查找的远程网页地址</param>
        /// <param name="timeout">超时时长设置，一般设置为8000</param>
        /// <param name="enterType">是否输出换行符，0不输出，1输出文本框换行</param>
        /// <param name="EnCodeType">编码方式</param>
        public static string GetRequestString(string strUrl, int timeout, int enterType, Encoding EnCodeType, params string[] Parms)
        {
            string strResult;
            try
            {
                HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl);
                //System.Net.Cache.HttpRequestCachePolicy policy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore);
                //myReq.CachePolicy = policy;
                myReq.Method = "GET";
                myReq.KeepAlive = true;

                Uri baseUri = new Uri(strUrl);
                myReq.Timeout = timeout;
                //myReq.Headers["Cache-Control"] = "max-age=0";
                myReq.Headers["Accept-Encoding"] = "gzip,deflate";
                myReq.Headers["Accept-Language"] = "zh-CN,zh;q=0.8";
                myReq.Headers["Accept-Charset"] = "GB2312,utf-8;q=0.7,*;q=0.7";
                if (Parms != null)
                {
                    if (!string.IsNullOrEmpty(Parms[0]))
                        myReq.Headers["Cookie"] = Parms[0];
                }
                myReq.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
                //myReq.Referer = strUrl;
                //myReq.UserAgent = "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36";
                myReq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;//自动解压缩

                HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();

                StringBuilder sb = new StringBuilder(40960);
                try
                {


                    Stream myStream = HttpWResp.GetResponseStream();
                    StreamReader sr = new StreamReader(myStream, EnCodeType);

                    while (!sr.EndOfStream)
                    {
                        sb.Append(sr.ReadLine());
                        if (enterType != 1)
                        {
                            sb.Replace("\r\n", "");
                            sb.Replace("\r", "");
                            sb.Replace("\n", "");
                        }
                    }
                    sr.Close();
                    sr.Dispose();

                }
                catch (Exception ex)
                {
                    strResult = "请求错误：" + strUrl + ex.Message;
                    throw new Exception("请求错误：" + strUrl + ex.Message);
                }
                finally
                {
                    
                    HttpWResp.Close();
                    myReq = null;
                    HttpWResp = null;
                }
                strResult = sb.ToString();
                sb.Remove(0, sb.Length);
            }
            catch (Exception err)
            {
                strResult = "请求错误：" + strUrl + err.Message;
                throw new Exception("请求错误：" + strUrl + err.Message);

            }
            return strResult;
        }
        #endregion


        #region 是否web
        /// <summary>
        /// 是否web
        /// </summary>
        /// <returns></returns>
        public static bool IsWeb()
        {
            if (System.Web.HttpContext.Current != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static bool IsHasDir(string path)
        {
           return Directory.Exists(path);
        }
        #endregion
        #region 生成0-9随机数
        /// <summary>
        /// 生成0-9随机数
        /// </summary>
        /// <param name="VcodeNum">生成长度</param>
        /// <returns></returns>
        public static string RndNum(int VcodeNum)
        {
            StringBuilder sb = new StringBuilder(VcodeNum);
            Random rand = new Random();
            for (int i = 1; i < VcodeNum + 1; i++)
            {
                int t = rand.Next(9);
                sb.AppendFormat("{0}", t);
            }
            return sb.ToString();

        }

        /// <summary>
        /// 生成随机26个字符窜
        /// </summary>
        /// <param name="VcodeNum"></param>
        /// <returns></returns>
        public static string RndChar(int VcodeNum)
        {
            string codestr = "abcdefghijklimnopqrstuvwxyz";
            int number;
            string checkCode = String.Empty;
            Random rnd = new Random();

            for (int i = 0; i < VcodeNum; i++)
            {
                number = rnd.Next(0, 26);
                checkCode = string.Concat(checkCode, codestr.Substring(number, 1));
            }
            return checkCode;

        }
        #endregion

        #region +++文件/文件夹

        #region "根据文件扩展名获取当前目录下的文件列表"
        /// <summary>
        /// 根据文件扩展名获取当前目录下的文件列表
        /// </summary>
        /// <param name="FileExt">文件扩展名</param>
        /// <returns>返回文件列表</returns>
        public static List<string> GetDirFileList(string path,string FileExt)
        {
            List<string> FilesList = new List<string>();
            string[] Files = Directory.GetFiles(path, string.Format("*.{0}", FileExt));
            foreach (string var in Files)
            {
                FilesList.Add(System.IO.Path.GetFileName(var).ToLower());
            }
            return FilesList;
        }
        #endregion

        /// <summary>
        ///返回文件内容.
        /// </summary>
        /// <param name="path">文件件物理路径</param>
        /// <returns>文件内容</returns>
        public static string GetFileContent(string path,Encoding encoding)
        {
            if (!File.Exists(path)) return "";
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
            if (fs == null) throw new IOException("Unable to open the file: " + path);
            StreamReader sr = new StreamReader(fs, encoding);
            string res = sr.ReadToEnd();
            sr.Close();
            return res;
        }

        /// <summary>
        /// 生成文件
        /// </summary>
        /// <param name="pathAndName">文件路径和名称</param>
        /// <param name="content">写入内容</param>
        /// <param name="encoding">存储编码 为空则为：gb2312</param>
        /// <returns></returns>
        public static bool CreateFile(string pathAndName, string content, Encoding encoding)
        {
            try
            {
                //指定日志文件的目录
                string fname = pathAndName;
                //定义文件信息对象
                FileInfo finfo = new FileInfo(fname);
                if (encoding == null)
                {
                    encoding = Encoding.GetEncoding("gb2312");
                }
                //判断文件是否存在以及是否大于2K
                if (finfo.Exists)
                {
                    //删除该文件
                    finfo.Delete();
                }
                else
                {
                  FileStream stream=  finfo.Create();
                  stream.Close();
    
                }
                //创建只写文件流
                using (FileStream fs = finfo.OpenWrite())
                {
                    //根据上面创建的文件流创建写数据流
                    StreamWriter w = new StreamWriter(fs,encoding);
                    //设置写数据流的起始位置为文件流的末尾
                    w.BaseStream.Seek(0, SeekOrigin.End);
                    w.Write(content);
                    //清空缓冲区内容，并把缓冲区内容写入基础流
                    w.Flush();
                    //关闭写数据流
                    w.Close();
                }
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        

        #region "获得物理路径"
        /// <summary>
        /// 获得物理路径
        /// </summary>
        /// <param name="a">路径</param>
        /// <returns>物理路径</returns>
        public static string GetFullPath(string a)
        {
            string AppDir = System.AppDomain.CurrentDomain.BaseDirectory;
            if (a.IndexOf(":") < 0)
            {
                string str = a.Replace("..\\", "");
                if (str != a)
                {
                    int Num = (a.Length - str.Length) / ("..\\").Length + 1;
                    for (int i = 0; i < Num; i++)
                    {
                        AppDir = AppDir.Substring(0, AppDir.LastIndexOf("\\"));
                    }
                    str = "\\" + str;

                }
                a = AppDir + str;
            }
            return a;
        }
        #endregion

        #region  获得当前绝对路径
        /// <summary>
        /// 获得当前绝对路径
        /// </summary>
        /// <param name="strPath">指定的路径</param>
        /// <returns>绝对路径</returns>
        public static string GetMapPath(string strPath)
        {
            if (IsWeb())
            {
           
                return HttpContext.Current.Server.MapPath(strPath);
            }
            else //非web程序引用
            {
                strPath = strPath.Replace("/", "\\");
                if (strPath.StartsWith("\\"))
                {
                    strPath = strPath.Substring(strPath.IndexOf('\\', 1)).TrimStart('\\');
                }
                return System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath);
            }
        }
        

        #endregion

        #region 获取根目录
        /// <summary>
        /// 获取根目录  最后有\\
        /// </summary>
        /// <returns></returns>
        public static string GetServerPath()
        {
            if (IsWeb())
            {
                return HttpContext.Current.Request.PhysicalApplicationPath;
            }
            else
            {
                return System.Windows.Forms.Application.StartupPath.ToString();
            }
        }
        #endregion

        #region 判断文件名是否为浏览器可以直接显示的图片文件名
        /// <summary>
        /// 判断文件名是否为浏览器可以直接显示的图片文件名
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>是否可以直接显示</returns>
        public static bool IsImgFilename(string filename)
        {
            filename = filename.Trim();
            if (filename.EndsWith(".") || filename.IndexOf(".") == -1)
            {
                return false;
            }
            string extname = filename.Substring(filename.LastIndexOf(".") + 1).ToLower();
            return (extname == "jpg" || extname == "jpeg" || extname == "png" || extname == "bmp" || extname == "gif");
        }
        #endregion

        

        #region 判断文件流是否为UTF8字符集
        //0000 0000-0000 007F - 0xxxxxxx  (ascii converts to 1 octet!)
        //0000 0080-0000 07FF - 110xxxxx 10xxxxxx    ( 2 octet format)
        //0000 0800-0000 FFFF - 1110xxxx 10xxxxxx 10xxxxxx (3 octet format)

        /// <summary>
        /// 判断文件流是否为UTF8字符集
        /// </summary>
        /// <param name="sbInputStream">文件流</param>
        /// <returns>判断结果</returns>
        private static bool FileStreamIsUTF8(FileStream sbInputStream)
        {
            int i;
            byte cOctets;  // octets to go in this UTF-8 encoded character 
            byte chr;
            bool bAllAscii = true;
            long iLen = sbInputStream.Length;

            cOctets = 0;
            for (i = 0; i < iLen; i++)
            {
                chr = (byte)sbInputStream.ReadByte();

                if ((chr & 0x80) != 0) bAllAscii = false;

                if (cOctets == 0)
                {
                    if (chr >= 0x80)
                    {
                        do
                        {
                            chr <<= 1;
                            cOctets++;
                        }
                        while ((chr & 0x80) != 0);

                        cOctets--;
                        if (cOctets == 0) return false;
                    }
                }
                else
                {
                    if ((chr & 0xC0) != 0x80)
                    {
                        return false;
                    }
                    cOctets--;
                }
            }

            if (cOctets > 0)
            {
                return false;
            }

            if (bAllAscii)
            {
                return false;
            }

            return true;

        }
        #endregion

        

        #region 建立文件夹
        /// <summary>
        /// 建立文件夹
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static bool CreateDir(string name)
        {
            return Utils.MakeSureDirectoryPathExists(name);
        }
        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="name">名称</param>
        /// <returns>创建是否成功</returns>
        [DllImport("dbgHelp", SetLastError = true)]
        private static extern bool MakeSureDirectoryPathExists(string name);
        #endregion

        #region 文件是否存在
        /// <summary>
        /// 返回文件是否存在
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>是否存在</returns>
        public static bool IsExistsFile(string filename)
        {
            return System.IO.File.Exists(filename);
        }
        #endregion

        #region 方法 -- 删除文件
        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="filename"></param>
        public static void DeleteFile(string filePathAndName)
        {
            
            if (File.Exists(filePathAndName))
            {
                try
                {
                    File.Delete(filePathAndName);
                }
                catch(IOException e)
                {
                    throw e;
                }
            }
        }
        #endregion

        #region 备份文件
        /// <summary>
        /// 备份文件
        /// </summary>
        /// <param name="sourceFileName">源文件名</param>
        /// <param name="destFileName">目标文件名</param>
        /// <param name="overwrite">当目标文件存在时是否覆盖</param>
        /// <returns>操作是否成功</returns>
        public static bool BackupFile(string sourceFileName, string destFileName, bool overwrite)
        {
            if (!System.IO.File.Exists(sourceFileName))
            {
                throw new FileNotFoundException(sourceFileName + "文件不存在！");
            }
            if (!overwrite && System.IO.File.Exists(destFileName))
            {
                return false;
            }
            try
            {
                System.IO.File.Copy(sourceFileName, destFileName, true);
                return true;
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        #endregion 

        #region 备份文件
        /// <summary>
        /// 备份文件,当目标文件存在时覆盖
        /// </summary>
        /// <param name="sourceFileName">源文件名</param>
        /// <param name="destFileName">目标文件名</param>
        /// <returns>操作是否成功</returns>
        public static bool BackupFile(string sourceFileName, string destFileName)
        {
            return BackupFile(sourceFileName, destFileName, true);
        }
        #endregion 

        #region 回复文件
        /// <summary>
        /// 恢复文件
        /// </summary>
        /// <param name="backupFileName">备份文件名</param>
        /// <param name="targetFileName">要恢复的文件名</param>
        /// <param name="backupTargetFileName">要恢复文件再次备份的名称,如果为null,则不再备份恢复文件</param>
        /// <returns>操作是否成功</returns>
        public static bool RestoreFile(string backupFileName, string targetFileName, string backupTargetFileName)
        {
            try
            {
                if (!System.IO.File.Exists(backupFileName))
                {
                    throw new FileNotFoundException(backupFileName + "文件不存在！");
                }
                if (backupTargetFileName != null)
                {
                    if (!System.IO.File.Exists(targetFileName))
                    {
                        throw new FileNotFoundException(targetFileName + "文件不存在！无法备份此文件！");
                    }
                    else
                    {
                        System.IO.File.Copy(targetFileName, backupTargetFileName, true);
                    }
                }
                System.IO.File.Delete(targetFileName);
                System.IO.File.Copy(backupFileName, targetFileName);
            }
            catch (Exception e)
            {
                throw e;
            }
            return true;
        }

        /// <summary>
        /// 恢复文件
        /// </summary>
        /// <param name="backupFileName"></param>
        /// <param name="targetFileName"></param>
        /// <returns></returns>
        public static bool RestoreFile(string backupFileName, string targetFileName)
        {
            return RestoreFile(backupFileName, targetFileName, null);
        }
        #endregion 
        #endregion




       


    } 
}
